﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.Xml;
using TSL.Model;
using System.Collections;
using System.Xml.Serialization;
using System.IO;
using HeatonResearchNeural.Feedforward;
using HeatonResearchNeural.Feedforward.Train;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;

namespace TSL
{
	/// <summary>
	/// Interaction logic for TestingWindos.xaml
	/// </summary>
	public partial class TestingWindos : Window
	{
        ArrayList trainingSet;
        int trainSetCount;

        List<Gesture> inputList;
        private Dictionary<string, string> outputDictionary;
        private NeuralModule nn ;
        private Neural network;
        private bool isUseHeaton = true;
        private String outputNo;

        Gesture testingGesture;

		public TestingWindos()
		{
			this.InitializeComponent();
			
			// Insert code required on object creation below this point.
            trainingSet = new ArrayList();
            trainSetCount = 0;
            this.inputList = new List<Gesture>();
            outputDictionary = new Dictionary<string, string>();
            nn = new NeuralModule();
            network = new Neural();
		}

        private void trainingAddButton_Click(object sender, RoutedEventArgs e)
        {
            string path;
            OpenFileDialog filePicker = new OpenFileDialog();
            filePicker.Filter = "Gesture (*.XML) |*.XML|" + "All files (*.*)|*.*";
            filePicker.Multiselect = true;
            filePicker.Title = "Select gestures";
            if (filePicker.ShowDialog().Value)
            {
                // Read the files
                foreach (String file in filePicker.FileNames)
                {
                    try
                    {
                        path = file;
                        path = path.Replace(@"\", @"\\");
                        trainingListBox.Text += path + "\r\n";
                        trainingSet.Add(path);
                        XMLModule xmlMod = new XMLModule();
                        Gesture inputGesture = xmlMod.DeserializeGesture(path);
                        this.inputList.Add(inputGesture);
                        trainSetCount++;
                        inputBox.Text += "Add new gesture to inputList : " + filePicker.FileName + "\r\n";
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Cannot load gesture: " + file.Substring(file.LastIndexOf('\\'))
                        + ". You may not have permission to read the file, or " +
                        "it may be corrupt.\n\nReported error: " + ex.Message);
                    }
                }
                //if (filePicker.CheckPathExists && filePicker.CheckPathExists)
                //{
                //    path = filePicker.FileName;
                //    path = path.Replace(@"\", @"\\");
                //    trainingListBox.Text += path + "\r\n";
                //    trainingSet.Add(path);
                //    XMLModule xmlMod = new XMLModule();
                //    Gesture inputGesture = xmlMod.DeserializeGesture(path);
                //    this.inputList.Add(inputGesture);
                //    trainSetCount++;
                //    inputBox.Text += "Add new gesture to inputList : " + filePicker.FileName + "\r\n";
                //}
            }
        }

        private void trainingClearButton_Click(object sender, RoutedEventArgs e)
        {
            trainSetCount = 0;
            trainingListBox.Text = "";
            for (int i = 0; i < trainingSet.Count; i++)
            {
                trainingSet[i] = "";
            }
        }

        private void inputBrowse_Click(object sender, RoutedEventArgs e)
        {
            inputBox.Text = "";
            string path;
            OpenFileDialog filePicker = new OpenFileDialog();
            filePicker.Filter = "Gesture (*.XML) |*.XML|" + "All files (*.*)|*.*";
            filePicker.Title = "Select gesture";
            filePicker.ShowDialog();
            if (filePicker.CheckPathExists && filePicker.CheckPathExists)
            {
                testingGesture = null;
                path = filePicker.FileName;
                path = path.Replace(@"\", @"\\");
                inputPath.Text = path;
                ReadInputXML(path);
            }
        }

        private void ReadInputXML(String path)
        {
            XMLModule xmlMod = new XMLModule();
            testingGesture = xmlMod.DeserializeGesture(path);
            inputBox.Text += "Gesture Name : " + testingGesture.GestureName + "\r\n";
            inputBox.Text += "Gesture By   : " + testingGesture.GestureBy + "\r\n";
            inputBox.Text += "Total Frames : " + testingGesture.TotalFrame.ToString() + "\r\n";

            #region Show input Details
            //for (int i = 0; i < inputGesture.TotalFrame; i++)
            //{
            //    for (int j = 0; j < 7; j++)
            //    {
            //        switch (j)
            //        {
            //            case 0:
            //                inputBox.Text += "    Head\r\n";
            //                inputBox.Text += "        X : " + inputGesture.GestureFrames[j].Head.X + "\r\n";
            //                inputBox.Text += "        Y : " + inputGesture.GestureFrames[j].Head.Y + "\r\n";
            //                inputBox.Text += "        Z : " + inputGesture.GestureFrames[j].Head.Z + "\r\n\r\n";
            //                break;
            //            case 1:
            //                inputBox.Text += "    HandLeft\r\n";
            //                inputBox.Text += "        X : " + inputGesture.GestureFrames[j].HandLeft.X + "\r\n";
            //                inputBox.Text += "        Y : " + inputGesture.GestureFrames[j].HandLeft.Y + "\r\n";
            //                inputBox.Text += "        Z : " + inputGesture.GestureFrames[j].HandLeft.Z + "\r\n\r\n";
            //                break;
            //            case 2:
            //                inputBox.Text += "    HandRight\r\n";
            //                inputBox.Text += "        X : " + inputGesture.GestureFrames[j].HandRight.X + "\r\n";
            //                inputBox.Text += "        Y : " + inputGesture.GestureFrames[j].HandRight.Y + "\r\n";
            //                inputBox.Text += "        Z : " + inputGesture.GestureFrames[j].HandRight.Z + "\r\n\r\n";
            //                break;
            //            case 3:
            //                inputBox.Text += "    ShoulderLeft\r\n";
            //                inputBox.Text += "        X : " + inputGesture.GestureFrames[j].ShoulderLeft.X + "\r\n";
            //                inputBox.Text += "        Y : " + inputGesture.GestureFrames[j].ShoulderLeft.Y + "\r\n";
            //                inputBox.Text += "        Z : " + inputGesture.GestureFrames[j].ShoulderLeft.Z + "\r\n\r\n";
            //                break;
            //            case 4:
            //                inputBox.Text += "    ShoulderRight\r\n";
            //                inputBox.Text += "        X : " + inputGesture.GestureFrames[j].ShoulderRight.X + "\r\n";
            //                inputBox.Text += "        Y : " + inputGesture.GestureFrames[j].ShoulderRight.Y + "\r\n";
            //                inputBox.Text += "        Z : " + inputGesture.GestureFrames[j].ShoulderRight.Z + "\r\n\r\n";
            //                break;
            //            case 5:
            //                inputBox.Text += "    HipLeft\r\n";
            //                inputBox.Text += "        X : " + inputGesture.GestureFrames[j].HipLeft.X + "\r\n";
            //                inputBox.Text += "        Y : " + inputGesture.GestureFrames[j].HipLeft.Y + "\r\n";
            //                inputBox.Text += "        Z : " + inputGesture.GestureFrames[j].HipLeft.Z + "\r\n\r\n";
            //                break;
            //            case 6:
            //                inputBox.Text += "    HipRight\r\n";
            //                inputBox.Text += "        X : " + inputGesture.GestureFrames[j].HipRight.X + "\r\n";
            //                inputBox.Text += "        Y : " + inputGesture.GestureFrames[j].HipRight.Y + "\r\n";
            //                inputBox.Text += "        Z : " + inputGesture.GestureFrames[j].HipRight.Z + "\r\n\r\n";
            //                break;
            //            default:
            //                break;
            //        }
            //    } 
            #endregion

            }

            

        	private void trainButton_Click(object sender, RoutedEventArgs e)
            {
                inputBox.Text += "Start Train At " + DateTime.Now.Hour + "." + DateTime.Now.Minute + "." + DateTime.Now.Second+"\r\n";
                inputBox.Text += "Train with "+inputList.Count + " files.\r\n";
                train();
            }

            private void train()
            {
                if (isUseHeaton)
                {
                    nn.CreateTrainingSet(inputList);
                    nn.Train(double.Parse(learningRate.Text), double.Parse(momentum.Text), int.Parse(trainingCycles.Text));
                    inputBox.Text += "Completed At " + DateTime.Now.Hour + "." + DateTime.Now.Minute + "." + DateTime.Now.Second + "\r\n";
                }
                else
                {
                    network.CreateNetwork();
                    network.CreateTrainingSet(inputList);
                    network.StartTrain((long)20000);
                }
            }

        	private void testButton_Click(object sender, RoutedEventArgs e)
            {
                ArrayList actual;
                if (isUseHeaton)
                {
                    actual = nn.TestNeural(testingGesture);
                }
                else
                {
                    actual = network.Run(testingGesture);
                }
                //double round = Math.Round(actual, 2, MidpointRounding.AwayFromZero);
                outputNo = "";
                inputBox.Text += "Actual Output : \r\n";
                foreach (double d in actual)
                {
                    inputBox.Text += "        "+ Math.Round(d, 0,MidpointRounding.AwayFromZero) + " >>> (" + d + ")\r\n";
                    outputNo += Math.Round(d, 0, MidpointRounding.AwayFromZero);
                }
                inputBox.Text += "=======================================\r\n";
                inputBox.Text += " = "+nn.findMeaning(outputNo)+"\r\n";
            }

			private void Button_Click_1(object sender, System.Windows.RoutedEventArgs e)
			{
                if (isUseHeaton)
                {
                    SaveFileDialog saveFileDialog1 = new SaveFileDialog();
                    saveFileDialog1.RestoreDirectory = true;
                    if (saveFileDialog1.ShowDialog() == true)
                    {
                        if (nn.SaveNeural(saveFileDialog1.FileName))
                        {
                            inputBox.Text += "Save network complete \r\n";
                        }
                    }
                }
                else
                {
                    SaveFileDialog saveFileDialog1 = new SaveFileDialog();
                    saveFileDialog1.RestoreDirectory = true;
                    if (saveFileDialog1.ShowDialog() == true)
                    {
                        if (network.Save(saveFileDialog1.FileName))
                        {
                            inputBox.Text += "Save network complete \r\n";
                        }
                    }
                }
			}

            private void Button_Click(object sender, RoutedEventArgs e)
            {
                //network.Load(@"C:\Kinect Data\network.xml");
                if (isUseHeaton)
                {
                    OpenFileDialog filePicker = new OpenFileDialog();
                    filePicker.Filter = "TSL (*.tsl) |*.tsl|" + "All files (*.*)|*.*"; 
                    if (filePicker.ShowDialog().Value)
                    {
                        if (filePicker.CheckPathExists && filePicker.CheckPathExists)
                        {
                            String path = filePicker.FileName;
                            path = path.Replace(@"\", @"\\");
                            if (nn.LoadNeural(path))
                            {
                                inputBox.Text += "Load network complete \r\n";
                            }
                        }
                    }
                }
                else
                {
                    OpenFileDialog filePicker = new OpenFileDialog();
                    if (filePicker.ShowDialog().Value)
                    {
                        if (filePicker.CheckPathExists && filePicker.CheckPathExists)
                        {
                            String path = filePicker.FileName;
                            path = path.Replace(@"\", @"\\");
                            if (network.Load(path))
                            {
                                inputBox.Text += "Load network complete \r\n";
                            }
                        }
                    }
                }
            }

            private void Button_Click_2(object sender, System.Windows.RoutedEventArgs e)
            {
                var mainmenu = new MainMenu();
                mainmenu.Show();
                this.Close();
            }

            private void RadioButton_Checked_1(object sender, System.Windows.RoutedEventArgs e)
            {
                isUseHeaton = true;
                inputBox.Text = "Use heaton \r\n";
            }

            private void RadioButton_Checked_2(object sender, System.Windows.RoutedEventArgs e)
            {
                isUseHeaton = false;
                inputBox.Text = "Use Brainnet \r\n";
            }

            private void RadioButton_Checked_3(object sender, System.Windows.RoutedEventArgs e)
            {
            	// TODO: Add event handler implementation here.
            }

            private void RadioButton_Checked_4(object sender, System.Windows.RoutedEventArgs e)
            {
            	// TODO: Add event handler implementation here.
            }
        }
	}